package com.poster.service.impl;

import com.poster.constant.JWTKeys;
import com.poster.constant.RedisConstant;
import com.poster.entity.dto.UserLoginDto;
import com.poster.entity.dto.UserRegisterDto;
import com.poster.entity.po.UserInfo;
import com.poster.entity.vo.UserProfileVo;
import com.poster.enums.ResultCode;
import com.poster.enums.SexEnum;
import com.poster.exceptions.BusinessException;
import com.poster.mappers.RoleMapper;
import com.poster.mappers.UserInfoMapper;
import com.poster.service.IAccountService;
import com.poster.utils.JWTUtils;
import com.poster.utils.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.UUID;

@Service
public class AccountService implements IAccountService {


    private final UserInfoMapper userInfoMapper;

    private final RoleMapper roleMapper;

    private final JWTUtils jwtUtils;

    private final static int TOKEN_EXPIRE_TIME = 7 * RedisConstant.EXPIRE_ONE_DAY ;

    public AccountService(UserInfoMapper userInfoMapper, JWTUtils jwtUtils, RoleMapper roleMapper) {
        this.userInfoMapper = userInfoMapper;
        this.jwtUtils = jwtUtils;
        this.roleMapper = roleMapper;
    }

    @Override
    public UserProfileVo login(UserLoginDto dto) {


        if (!userInfoMapper.existsAccount(dto.getAccount())){
            throw new BusinessException(ResultCode.USER_LOGIN_ERROR);
        }

        UserInfo userInfo = userInfoMapper.selectByAccount(dto.getAccount());

        if (!dto.getPassword().equals(userInfo.getPassword())){
            throw new BusinessException(ResultCode.USER_LOGIN_ERROR);
        }

        String token = jwtUtils.createJWT(b -> {
            b.withClaim(JWTKeys.USER_ID, userInfo.getId());
            b.withClaim(JWTKeys.ROLE_ID, userInfo.getRoleId());
        }, TOKEN_EXPIRE_TIME);

        UserProfileVo profile = new UserProfileVo();

        profile.setCode(userInfo.getCode());
        profile.setName(userInfo.getName());
        profile.setAccount(userInfo.getAccount());
        profile.setStatus(userInfo.getStatus());
        profile.setAvatarUrl(userInfo.getAvatarUrl());
        profile.setSex(userInfo.getSex());
        profile.setLastLoginIp(userInfo.getLastLoginIp());
        profile.setToken(token);

        return profile;
    }

    @Override
    public void register(UserRegisterDto dto) {

        if (userInfoMapper.existsAccount(dto.getAccount())){
            throw new BusinessException(ResultCode.USER_HAS_EXISTED);
        }

        UserInfo bean = new UserInfo();


        bean.setPassword(StringUtils.md5(dto.getPassword()));
        bean.setCode(UUID.randomUUID().toString());
        bean.setSex(SexEnum.UNKNOW.getCode());
        bean.setCreateAt(LocalDateTime.now());
        bean.setPhoneNumber(dto.getPhoneNumber());
        bean.setIdNumber(dto.getIdNumber());
        bean.setName(dto.getName());
        bean.setAccount(dto.getAccount());

        // TODO redis code -> id 映射表

        Integer roleId = roleMapper.selectIdByCode(dto.getRoleCode());

        if (roleId == null){
            throw new BusinessException(ResultCode.PARAM_IS_INVALID);
        }

        bean.setRoleId(roleId);

        userInfoMapper.insert(bean);

    }

}
